

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>Image View - Boost.GIL  documentation</title>
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    <link rel="stylesheet" href="../_static/style.css" type="text/css" />
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
          URL_ROOT:    '../',
          VERSION:     '',
          COLLAPSE_MODINDEX: false,
          FILE_SUFFIX: '.html'
      };
    </script>
    <script type="text/javascript" src="../_static/jquery.js"></script>
    <script type="text/javascript" src="../_static/underscore.js"></script>
    <script type="text/javascript" src="../_static/doctools.js"></script>
    <link rel="index" title="Index" href="../genindex.html" />
    <link rel="search" title="Search" href="../search.html" />
    <link rel="top" title="Boost.GIL  documentation" href="../index.html" />
    <link rel="up" title="Design Guide" href="index.html" />
    <link rel="next" title="Image" href="image.html" />
    <link rel="prev" title="Pixel Locator" href="pixel_locator.html" /> 
  </head>
  <body>
    <div class="header">
    <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
    "header">
      <tr>
        <td valign="top" width="300">
          <h3><a href="../index.html"><img
          alt="C++ Boost" src="../_static/gil.png" border="0"></a></h3>
        </td>

        <td >
          <h1 align="center"><a href="../index.html"></a></h1>
        </td>
	<td>
      <div id="searchbox" style="display: none">
        <form class="search" action="../search.html" method="get">
          <input type="text" name="q" size="18" />
          <input type="submit" value="Search" />
          <input type="hidden" name="check_keywords" value="yes" />
          <input type="hidden" name="area" value="default" />
        </form>
      </div>
      <script type="text/javascript">$('#searchbox').show(0);</script>
	</td>
      </tr>
    </table>
    </div>
    <hr/>
    <div class="content">
    <div class="navbar" style="text-align:right;">
      
      
      <a class="prev" title="Pixel Locator" href="pixel_locator.html"><img src="../_static/prev.png" alt="prev"/></a>
      <a class="up" title="Design Guide" href="index.html"><img src="../_static/up.png" alt="up"/></a>
      <a class="next" title="Image" href="image.html"><img src="../_static/next.png" alt="next"/></a>
      
    </div>
      
  <div class="section" id="image-view">
<h1>Image View</h1>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#overview" id="id1">Overview</a></li>
<li><a class="reference internal" href="#models" id="id2">Models</a></li>
<li><a class="reference internal" href="#algorithms" id="id3">Algorithms</a><ul>
<li><a class="reference internal" href="#creating-views-from-raw-pixels" id="id4">Creating Views from Raw Pixels</a></li>
<li><a class="reference internal" href="#creating-image-views-from-other-image-views" id="id5">Creating Image Views from Other Image Views</a></li>
<li><a class="reference internal" href="#stl-style-algorithms-on-image-views" id="id6">STL-Style Algorithms on Image Views</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="overview">
<h2><a class="toc-backref" href="#id1">Overview</a></h2>
<p>An image view is a generalization of STL range concept to multiple dimensions.
Similar to ranges (and iterators), image views are shallow, don&#8217;t own the
underlying data and don&#8217;t propagate their constness over the data.
For example, a constant image view cannot be resized, but may allow modifying
the pixels. For pixel-immutable operations, use constant-value image view
(also called non-mutable image view). Most general N-dimensional views satisfy
the following concept:</p>
<div class="highlight-cpp"><div class="highlight"><pre><span></span><span class="n">concept</span> <span class="n">RandomAccessNDImageViewConcept</span><span class="o">&lt;</span><span class="n">Regular</span> <span class="n">View</span><span class="o">&gt;</span>
<span class="p">{</span>
  <span class="k">typename</span> <span class="n">value_type</span><span class="p">;</span>      <span class="c1">// for pixel-based views, the pixel type</span>
  <span class="k">typename</span> <span class="n">reference</span><span class="p">;</span>       <span class="c1">// result of dereferencing</span>
  <span class="k">typename</span> <span class="n">difference_type</span><span class="p">;</span> <span class="c1">// result of operator-(iterator,iterator) (1-dimensional!)</span>
  <span class="k">typename</span> <span class="n">const_t</span><span class="p">;</span>  <span class="n">where</span> <span class="n">RandomAccessNDImageViewConcept</span><span class="o">&lt;</span><span class="n">View</span><span class="o">&gt;</span><span class="p">;</span> <span class="c1">// same as View, but over immutable values</span>
  <span class="k">typename</span> <span class="n">point_t</span><span class="p">;</span>  <span class="n">where</span> <span class="n">PointNDConcept</span><span class="o">&lt;</span><span class="n">point_t</span><span class="o">&gt;</span><span class="p">;</span> <span class="c1">// N-dimensional point</span>
  <span class="k">typename</span> <span class="n">locator</span><span class="p">;</span>  <span class="n">where</span> <span class="n">RandomAccessNDLocatorConcept</span><span class="o">&lt;</span><span class="n">locator</span><span class="o">&gt;</span><span class="p">;</span> <span class="c1">// N-dimensional locator.</span>
  <span class="k">typename</span> <span class="n">iterator</span><span class="p">;</span> <span class="n">where</span> <span class="n">RandomAccessTraversalConcept</span><span class="o">&lt;</span><span class="n">iterator</span><span class="o">&gt;</span><span class="p">;</span> <span class="c1">// 1-dimensional iterator over all values</span>
  <span class="k">typename</span> <span class="n">reverse_iterator</span><span class="p">;</span> <span class="n">where</span> <span class="n">RandomAccessTraversalConcept</span><span class="o">&lt;</span><span class="n">reverse_iterator</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="k">typename</span> <span class="n">size_type</span><span class="p">;</span>       <span class="c1">// the return value of size()</span>

  <span class="c1">// Equivalent to RandomAccessNDLocatorConcept::axis</span>
  <span class="k">template</span> <span class="o">&lt;</span><span class="kt">size_t</span> <span class="n">D</span><span class="o">&gt;</span> <span class="k">struct</span> <span class="n">axis</span> <span class="p">{</span>
      <span class="k">typename</span> <span class="n">coord_t</span> <span class="o">=</span> <span class="n">point_t</span><span class="o">::</span><span class="n">axis</span><span class="o">&lt;</span><span class="n">D</span><span class="o">&gt;::</span><span class="n">coord_t</span><span class="p">;</span>
      <span class="k">typename</span> <span class="n">iterator</span><span class="p">;</span> <span class="n">where</span> <span class="n">RandomAccessTraversalConcept</span><span class="o">&lt;</span><span class="n">iterator</span><span class="o">&gt;</span><span class="p">;</span>   <span class="c1">// iterator along D-th axis.</span>
      <span class="n">where</span> <span class="n">SameType</span><span class="o">&lt;</span><span class="n">coord_t</span><span class="p">,</span> <span class="n">iterator</span><span class="o">::</span><span class="n">difference_type</span><span class="o">&gt;</span><span class="p">;</span>
      <span class="n">where</span> <span class="n">SameType</span><span class="o">&lt;</span><span class="n">iterator</span><span class="o">::</span><span class="n">value_type</span><span class="p">,</span><span class="n">value_type</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="p">};</span>

  <span class="c1">// Defines the type of a view similar to this type, except it invokes Deref upon dereferencing</span>
  <span class="k">template</span> <span class="o">&lt;</span><span class="n">PixelDereferenceAdaptorConcept</span> <span class="n">Deref</span><span class="o">&gt;</span> <span class="k">struct</span> <span class="n">add_deref</span> <span class="p">{</span>
      <span class="k">typename</span> <span class="n">type</span><span class="p">;</span>        <span class="n">where</span> <span class="n">RandomAccessNDImageViewConcept</span><span class="o">&lt;</span><span class="n">type</span><span class="o">&gt;</span><span class="p">;</span>
      <span class="k">static</span> <span class="n">type</span> <span class="nf">make</span><span class="p">(</span><span class="k">const</span> <span class="n">View</span><span class="o">&amp;</span> <span class="n">v</span><span class="p">,</span> <span class="k">const</span> <span class="n">Deref</span><span class="o">&amp;</span> <span class="n">deref</span><span class="p">);</span>
  <span class="p">};</span>

  <span class="k">static</span> <span class="k">const</span> <span class="kt">size_t</span> <span class="n">num_dimensions</span> <span class="o">=</span> <span class="n">point_t</span><span class="o">::</span><span class="n">num_dimensions</span><span class="p">;</span>

  <span class="c1">// Create from a locator at the top-left corner and dimensions</span>
  <span class="n">View</span><span class="o">::</span><span class="n">View</span><span class="p">(</span><span class="k">const</span> <span class="n">locator</span><span class="o">&amp;</span><span class="p">,</span> <span class="k">const</span> <span class="n">point_type</span><span class="o">&amp;</span><span class="p">);</span>

  <span class="n">size_type</span>        <span class="n">View</span><span class="o">::</span><span class="n">size</span><span class="p">()</span>       <span class="k">const</span><span class="p">;</span> <span class="c1">// total number of elements</span>
  <span class="n">reference</span>        <span class="k">operator</span><span class="p">[](</span><span class="n">View</span><span class="p">,</span> <span class="k">const</span> <span class="n">difference_type</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span> <span class="c1">// 1-dimensional reference</span>
  <span class="n">iterator</span>         <span class="n">View</span><span class="o">::</span><span class="n">begin</span><span class="p">()</span>      <span class="k">const</span><span class="p">;</span>
  <span class="n">iterator</span>         <span class="n">View</span><span class="o">::</span><span class="n">end</span><span class="p">()</span>        <span class="k">const</span><span class="p">;</span>
  <span class="n">reverse_iterator</span> <span class="n">View</span><span class="o">::</span><span class="n">rbegin</span><span class="p">()</span>     <span class="k">const</span><span class="p">;</span>
  <span class="n">reverse_iterator</span> <span class="n">View</span><span class="o">::</span><span class="n">rend</span><span class="p">()</span>       <span class="k">const</span><span class="p">;</span>
  <span class="n">iterator</span>         <span class="n">View</span><span class="o">::</span><span class="n">at</span><span class="p">(</span><span class="k">const</span> <span class="n">point_t</span><span class="o">&amp;</span><span class="p">);</span>
  <span class="n">point_t</span>          <span class="n">View</span><span class="o">::</span><span class="n">dimensions</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span> <span class="c1">// number of elements along each dimension</span>
  <span class="kt">bool</span>             <span class="n">View</span><span class="o">::</span><span class="n">is_1d_traversable</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>   <span class="c1">// Does an iterator over the first dimension visit each value?</span>

  <span class="c1">// iterator along a given dimension starting at a given point</span>
  <span class="k">template</span> <span class="o">&lt;</span><span class="kt">size_t</span> <span class="n">D</span><span class="o">&gt;</span> <span class="n">View</span><span class="o">::</span><span class="n">axis</span><span class="o">&lt;</span><span class="n">D</span><span class="o">&gt;::</span><span class="n">iterator</span> <span class="n">View</span><span class="o">::</span><span class="n">axis_iterator</span><span class="p">(</span><span class="k">const</span> <span class="n">point_t</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>

  <span class="n">reference</span> <span class="nf">operator</span><span class="p">()(</span><span class="n">View</span><span class="p">,</span><span class="k">const</span> <span class="n">point_t</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
<span class="p">};</span>

<span class="n">concept</span> <span class="n">MutableRandomAccessNDImageViewConcept</span><span class="o">&lt;</span><span class="n">RandomAccessNDImageViewConcept</span> <span class="n">View</span><span class="o">&gt;</span>
<span class="p">{</span>
  <span class="n">where</span> <span class="n">Mutable</span><span class="o">&lt;</span><span class="n">reference</span><span class="o">&gt;</span><span class="p">;</span>
<span class="p">};</span>
</pre></div>
</div>
<p>Two-dimensional image views have the following extra requirements:</p>
<div class="highlight-cpp"><div class="highlight"><pre><span></span><span class="n">concept</span> <span class="n">RandomAccess2DImageViewConcept</span><span class="o">&lt;</span><span class="n">RandomAccessNDImageViewConcept</span> <span class="n">View</span><span class="o">&gt;</span>
<span class="p">{</span>
  <span class="n">where</span> <span class="n">num_dimensions</span><span class="o">==</span><span class="mi">2</span><span class="p">;</span>

  <span class="k">typename</span> <span class="n">x_iterator</span> <span class="o">=</span> <span class="n">axis</span><span class="o">&lt;</span><span class="mi">0</span><span class="o">&gt;::</span><span class="n">iterator</span><span class="p">;</span>
  <span class="k">typename</span> <span class="n">y_iterator</span> <span class="o">=</span> <span class="n">axis</span><span class="o">&lt;</span><span class="mi">1</span><span class="o">&gt;::</span><span class="n">iterator</span><span class="p">;</span>
  <span class="k">typename</span> <span class="n">x_coord_t</span>  <span class="o">=</span> <span class="n">axis</span><span class="o">&lt;</span><span class="mi">0</span><span class="o">&gt;::</span><span class="n">coord_t</span><span class="p">;</span>
  <span class="k">typename</span> <span class="n">y_coord_t</span>  <span class="o">=</span> <span class="n">axis</span><span class="o">&lt;</span><span class="mi">1</span><span class="o">&gt;::</span><span class="n">coord_t</span><span class="p">;</span>
  <span class="k">typename</span> <span class="n">xy_locator</span> <span class="o">=</span> <span class="n">locator</span><span class="p">;</span>

  <span class="n">x_coord_t</span> <span class="n">View</span><span class="o">::</span><span class="n">width</span><span class="p">()</span>  <span class="k">const</span><span class="p">;</span>
  <span class="n">y_coord_t</span> <span class="n">View</span><span class="o">::</span><span class="n">height</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>

  <span class="c1">// X-navigation</span>
  <span class="n">x_iterator</span> <span class="n">View</span><span class="o">::</span><span class="n">x_at</span><span class="p">(</span><span class="k">const</span> <span class="n">point_t</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
  <span class="n">x_iterator</span> <span class="n">View</span><span class="o">::</span><span class="n">row_begin</span><span class="p">(</span><span class="n">y_coord_t</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
  <span class="n">x_iterator</span> <span class="n">View</span><span class="o">::</span><span class="n">row_end</span>  <span class="p">(</span><span class="n">y_coord_t</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>

  <span class="c1">// Y-navigation</span>
  <span class="n">y_iterator</span> <span class="n">View</span><span class="o">::</span><span class="n">y_at</span><span class="p">(</span><span class="k">const</span> <span class="n">point_t</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
  <span class="n">y_iterator</span> <span class="n">View</span><span class="o">::</span><span class="n">col_begin</span><span class="p">(</span><span class="n">x_coord_t</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
  <span class="n">y_iterator</span> <span class="n">View</span><span class="o">::</span><span class="n">col_end</span>  <span class="p">(</span><span class="n">x_coord_t</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>

  <span class="c1">// navigating in 2D</span>
  <span class="n">xy_locator</span> <span class="n">View</span><span class="o">::</span><span class="n">xy_at</span><span class="p">(</span><span class="k">const</span> <span class="n">point_t</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>

  <span class="c1">// (x,y) versions of all methods taking point_t</span>
  <span class="n">View</span><span class="o">::</span><span class="n">View</span><span class="p">(</span><span class="n">x_coord_t</span><span class="p">,</span><span class="n">y_coord_t</span><span class="p">,</span><span class="k">const</span> <span class="n">locator</span><span class="o">&amp;</span><span class="p">);</span>
  <span class="n">iterator</span> <span class="n">View</span><span class="o">::</span><span class="n">at</span><span class="p">(</span><span class="n">x_coord_t</span><span class="p">,</span><span class="n">y_coord_t</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
  <span class="n">reference</span> <span class="nf">operator</span><span class="p">()(</span><span class="n">View</span><span class="p">,</span><span class="n">x_coord_t</span><span class="p">,</span><span class="n">y_coord_t</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
  <span class="n">xy_locator</span> <span class="n">View</span><span class="o">::</span><span class="n">xy_at</span><span class="p">(</span><span class="n">x_coord_t</span><span class="p">,</span><span class="n">y_coord_t</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
  <span class="n">x_iterator</span> <span class="n">View</span><span class="o">::</span><span class="n">x_at</span><span class="p">(</span><span class="n">x_coord_t</span><span class="p">,</span><span class="n">y_coord_t</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
  <span class="n">y_iterator</span> <span class="n">View</span><span class="o">::</span><span class="n">y_at</span><span class="p">(</span><span class="n">x_coord_t</span><span class="p">,</span><span class="n">y_coord_t</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
<span class="p">};</span>

<span class="n">concept</span> <span class="n">MutableRandomAccess2DImageViewConcept</span><span class="o">&lt;</span><span class="n">RandomAccess2DImageViewConcept</span> <span class="n">View</span><span class="o">&gt;</span>
  <span class="o">:</span> <span class="n">MutableRandomAccessNDImageViewConcept</span><span class="o">&lt;</span><span class="n">View</span><span class="o">&gt;</span> <span class="p">{};</span>
</pre></div>
</div>
<p>Image views that GIL typically uses operate on value types that model
<code class="docutils literal"><span class="pre">PixelValueConcept</span></code> and have some additional requirements:</p>
<div class="highlight-cpp"><div class="highlight"><pre><span></span><span class="n">concept</span> <span class="n">ImageViewConcept</span><span class="o">&lt;</span><span class="n">RandomAccess2DImageViewConcept</span> <span class="n">View</span><span class="o">&gt;</span>
<span class="p">{</span>
  <span class="n">where</span> <span class="n">PixelValueConcept</span><span class="o">&lt;</span><span class="n">value_type</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="n">where</span> <span class="n">PixelIteratorConcept</span><span class="o">&lt;</span><span class="n">x_iterator</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="n">where</span> <span class="n">PixelIteratorConcept</span><span class="o">&lt;</span><span class="n">y_iterator</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="n">where</span> <span class="n">x_coord_t</span> <span class="o">==</span> <span class="n">y_coord_t</span><span class="p">;</span>

  <span class="k">typename</span> <span class="n">coord_t</span> <span class="o">=</span> <span class="n">x_coord_t</span><span class="p">;</span>

  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">View</span><span class="o">::</span><span class="n">num_channels</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
<span class="p">};</span>


<span class="n">concept</span> <span class="n">MutableImageViewConcept</span><span class="o">&lt;</span><span class="n">ImageViewConcept</span> <span class="n">View</span><span class="o">&gt;</span>
  <span class="o">:</span> <span class="n">MutableRandomAccess2DImageViewConcept</span><span class="o">&lt;</span><span class="n">View</span><span class="o">&gt;</span>
<span class="p">{};</span>
</pre></div>
</div>
<p>Two image views are compatible if they have compatible pixels and the same
number of dimensions:</p>
<div class="highlight-cpp"><div class="highlight"><pre><span></span><span class="n">concept</span> <span class="n">ViewsCompatibleConcept</span><span class="o">&lt;</span><span class="n">ImageViewConcept</span> <span class="n">V1</span><span class="p">,</span> <span class="n">ImageViewConcept</span> <span class="n">V2</span><span class="o">&gt;</span>
<span class="p">{</span>
  <span class="n">where</span> <span class="n">PixelsCompatibleConcept</span><span class="o">&lt;</span><span class="n">V1</span><span class="o">::</span><span class="n">value_type</span><span class="p">,</span> <span class="n">V2</span><span class="o">::</span><span class="n">value_type</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="n">where</span> <span class="n">V1</span><span class="o">::</span><span class="n">num_dimensions</span> <span class="o">==</span> <span class="n">V2</span><span class="o">::</span><span class="n">num_dimensions</span><span class="p">;</span>
<span class="p">};</span>
</pre></div>
</div>
<p>Compatible views must also have the same dimensions (i.e. the same width and
height). Many algorithms taking multiple views require that they be pairwise
compatible.</p>
<div class="admonition seealso">
<p class="first admonition-title">See also</p>
<ul class="last simple">
<li><a class="reference external" href="reference/structboost_1_1gil_1_1_random_access_n_d_image_view_concept.html">RandomAccessNDImageViewConcept&lt;View&gt;</a></li>
<li><a class="reference external" href="reference/structboost_1_1gil_1_1_mutable_random_access_n_d_image_view_concept.html">MutableRandomAccessNDImageViewConcept&lt;View&gt;</a></li>
<li><a class="reference external" href="reference/structboost_1_1gil_1_1_random_access2_d_image_view_concept.html">RandomAccess2DImageViewConcept&lt;View&gt;</a></li>
<li><a class="reference external" href="reference/structboost_1_1gil_1_1_mutable_random_access2_d_image_view_concept.html">MutableRandomAccess2DImageViewConcept&lt;View&gt;</a></li>
<li><a class="reference external" href="reference/structboost_1_1gil_1_1_image_view_concept.html">ImageViewConcept&lt;View&gt;</a></li>
<li><a class="reference external" href="reference/structboost_1_1gil_1_1_mutable_image_view_concept.html">MutableImageViewConcept&lt;View&gt;</a></li>
<li><a class="reference external" href="reference/structboost_1_1gil_1_1_views_compatible_concept.html">ViewsCompatibleConcept&lt;View1,View2&gt;</a></li>
</ul>
</div>
</div>
<div class="section" id="models">
<h2><a class="toc-backref" href="#id2">Models</a></h2>
<p>GIL provides a model for <code class="docutils literal"><span class="pre">ImageViewConcept</span></code> called <code class="docutils literal"><span class="pre">image_view</span></code>. It is
templated over a model of <code class="docutils literal"><span class="pre">PixelLocatorConcept</span></code>. (If instantiated with a
model of <code class="docutils literal"><span class="pre">MutablePixelLocatorConcept</span></code>, it models
<code class="docutils literal"><span class="pre">MutableImageViewConcept</span></code>). Synopsis:</p>
<div class="highlight-cpp"><div class="highlight"><pre><span></span><span class="c1">// Locator models PixelLocatorConcept, could be MutablePixelLocatorConcept</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Locator</span><span class="o">&gt;</span>
<span class="k">class</span> <span class="nc">image_view</span>
<span class="p">{</span>
<span class="k">public</span><span class="o">:</span>
  <span class="k">typedef</span> <span class="n">Locator</span> <span class="n">xy_locator</span><span class="p">;</span>
  <span class="k">typedef</span> <span class="n">iterator_from_2d</span><span class="o">&lt;</span><span class="n">Locator</span><span class="o">&gt;</span> <span class="n">iterator</span><span class="p">;</span>
  <span class="p">...</span>
<span class="k">private</span><span class="o">:</span>
  <span class="n">xy_locator</span> <span class="n">_pixels</span><span class="p">;</span>     <span class="c1">// 2D pixel locator at the top left corner of the image view range</span>
  <span class="n">point_t</span>    <span class="n">_dimensions</span><span class="p">;</span> <span class="c1">// width and height</span>
<span class="p">};</span>
</pre></div>
</div>
<p>Image views are lightweight objects. A regular interleaved view is typically
16 bytes long - two integers for the width and height (inside dimensions) one
for the number of bytes between adjacent rows (inside the locator) and one
pointer to the beginning of the pixel block.</p>
</div>
<div class="section" id="algorithms">
<h2><a class="toc-backref" href="#id3">Algorithms</a></h2>
<p>GIL provides algorithms constructing views from raw data or other views.</p>
<div class="section" id="creating-views-from-raw-pixels">
<h3><a class="toc-backref" href="#id4">Creating Views from Raw Pixels</a></h3>
<p>Standard image views can be constructed from raw data of any supported color
space, bit depth, channel ordering or planar vs. interleaved structure.
Interleaved views are constructed using <code class="docutils literal"><span class="pre">interleaved_view</span></code>, supplying the
image dimensions, number of bytes per row, and a pointer to the first pixel:</p>
<div class="highlight-cpp"><div class="highlight"><pre><span></span><span class="c1">// Iterator models pixel iterator (e.g. rgb8_ptr_t or rgb8c_ptr_t)</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Iterator</span><span class="o">&gt;</span>
<span class="n">image_view</span><span class="o">&lt;</span><span class="p">...</span><span class="o">&gt;</span> <span class="n">interleaved_view</span><span class="p">(</span><span class="kt">ptrdiff_t</span> <span class="n">width</span><span class="p">,</span> <span class="kt">ptrdiff_t</span> <span class="n">height</span><span class="p">,</span> <span class="n">Iterator</span> <span class="n">pixels</span><span class="p">,</span> <span class="kt">ptrdiff_t</span> <span class="n">rowsize</span><span class="p">)</span>
</pre></div>
</div>
<p>Planar views are defined for every color space and take each plane separately.
Here is the RGB one:</p>
<div class="highlight-cpp"><div class="highlight"><pre><span></span><span class="c1">// Iterator models channel iterator (e.g. bits8* or bits8 const*)</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Iterator</span><span class="o">&gt;</span>
<span class="n">image_view</span><span class="o">&lt;</span><span class="p">...</span><span class="o">&gt;</span> <span class="n">planar_rgb_view</span><span class="p">(</span>
    <span class="kt">ptrdiff_t</span> <span class="n">width</span><span class="p">,</span> <span class="kt">ptrdiff_t</span> <span class="n">height</span><span class="p">,</span>
    <span class="n">IC</span> <span class="n">r</span><span class="p">,</span> <span class="n">IC</span> <span class="n">g</span><span class="p">,</span> <span class="n">IC</span> <span class="n">b</span><span class="p">,</span> <span class="kt">ptrdiff_t</span> <span class="n">rowsize</span><span class="p">);</span>
</pre></div>
</div>
<p>Note that the supplied pixel/channel iterators could be constant (read-only),
in which case the returned view is a constant-value (immutable) view.</p>
</div>
<div class="section" id="creating-image-views-from-other-image-views">
<h3><a class="toc-backref" href="#id5">Creating Image Views from Other Image Views</a></h3>
<p>It is possible to construct one image view from another by changing some
policy of how image data is interpreted. The result could be a view whose type
is derived from the type of the source. GIL uses the following metafunctions
to get the derived types:</p>
<div class="highlight-cpp"><div class="highlight"><pre><span></span><span class="c1">// Some result view types</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">View</span><span class="o">&gt;</span>
<span class="k">struct</span> <span class="nl">dynamic_xy_step_type</span> <span class="p">:</span> <span class="k">public</span> <span class="n">dynamic_y_step_type</span><span class="o">&lt;</span><span class="k">typename</span> <span class="n">dynamic_x_step_type</span><span class="o">&lt;</span><span class="n">View</span><span class="o">&gt;::</span><span class="n">type</span><span class="o">&gt;</span> <span class="p">{};</span>

<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">View</span><span class="o">&gt;</span>
<span class="k">struct</span> <span class="nl">dynamic_xy_step_transposed_type</span> <span class="p">:</span> <span class="k">public</span> <span class="n">dynamic_xy_step_type</span><span class="o">&lt;</span><span class="k">typename</span> <span class="n">transposed_type</span><span class="o">&lt;</span><span class="n">View</span><span class="o">&gt;::</span><span class="n">type</span><span class="o">&gt;</span> <span class="p">{};</span>

<span class="c1">// color and bit depth converted view to match pixel type P</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">SrcView</span><span class="p">,</span> <span class="c1">// Models ImageViewConcept</span>
        <span class="k">typename</span> <span class="n">DstP</span><span class="p">,</span>    <span class="c1">// Models PixelConcept</span>
        <span class="k">typename</span> <span class="n">ColorConverter</span><span class="o">=</span><span class="n">gil</span><span class="o">::</span><span class="n">default_color_converter</span><span class="o">&gt;</span>
<span class="k">struct</span> <span class="n">color_converted_view_type</span>
<span class="p">{</span>
  <span class="k">typedef</span> <span class="p">...</span> <span class="n">type</span><span class="p">;</span>     <span class="c1">// image view adaptor with value type DstP, over SrcView</span>
<span class="p">};</span>

<span class="c1">// single-channel view of the N-th channel of a given view</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">SrcView</span><span class="o">&gt;</span>
<span class="k">struct</span> <span class="n">nth_channel_view_type</span>
<span class="p">{</span>
  <span class="k">typedef</span> <span class="p">...</span> <span class="n">type</span><span class="p">;</span>
<span class="p">};</span>
</pre></div>
</div>
<p>GIL Provides the following view transformations:</p>
<div class="highlight-cpp"><div class="highlight"><pre><span></span><span class="c1">// flipped upside-down, left-to-right, transposed view</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">View</span><span class="o">&gt;</span> <span class="k">typename</span> <span class="n">dynamic_y_step_type</span><span class="o">&lt;</span><span class="n">View</span><span class="o">&gt;::</span><span class="n">type</span>             <span class="n">flipped_up_down_view</span><span class="p">(</span><span class="k">const</span> <span class="n">View</span><span class="o">&amp;</span> <span class="n">src</span><span class="p">);</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">View</span><span class="o">&gt;</span> <span class="k">typename</span> <span class="n">dynamic_x_step_type</span><span class="o">&lt;</span><span class="n">View</span><span class="o">&gt;::</span><span class="n">type</span>             <span class="n">flipped_left_right_view</span><span class="p">(</span><span class="k">const</span> <span class="n">View</span><span class="o">&amp;</span> <span class="n">src</span><span class="p">);</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">View</span><span class="o">&gt;</span> <span class="k">typename</span> <span class="n">dynamic_xy_step_transposed_type</span><span class="o">&lt;</span><span class="n">View</span><span class="o">&gt;::</span><span class="n">type</span> <span class="n">transposed_view</span><span class="p">(</span><span class="k">const</span> <span class="n">View</span><span class="o">&amp;</span> <span class="n">src</span><span class="p">);</span>

<span class="c1">// rotations</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">View</span><span class="o">&gt;</span> <span class="k">typename</span> <span class="n">dynamic_xy_step_type</span><span class="o">&lt;</span><span class="n">View</span><span class="o">&gt;::</span><span class="n">type</span>            <span class="n">rotated180_view</span><span class="p">(</span><span class="k">const</span> <span class="n">View</span><span class="o">&amp;</span> <span class="n">src</span><span class="p">);</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">View</span><span class="o">&gt;</span> <span class="k">typename</span> <span class="n">dynamic_xy_step_transposed_type</span><span class="o">&lt;</span><span class="n">View</span><span class="o">&gt;::</span><span class="n">type</span> <span class="n">rotated90cw_view</span><span class="p">(</span><span class="k">const</span> <span class="n">View</span><span class="o">&amp;</span> <span class="n">src</span><span class="p">);</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">View</span><span class="o">&gt;</span> <span class="k">typename</span> <span class="n">dynamic_xy_step_transposed_type</span><span class="o">&lt;</span><span class="n">View</span><span class="o">&gt;::</span><span class="n">type</span> <span class="n">rotated90ccw_view</span><span class="p">(</span><span class="k">const</span> <span class="n">View</span><span class="o">&amp;</span> <span class="n">src</span><span class="p">);</span>

<span class="c1">// view of an axis-aligned rectangular area within an image</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">View</span><span class="o">&gt;</span> <span class="n">View</span>                                                 <span class="n">subimage_view</span><span class="p">(</span><span class="k">const</span> <span class="n">View</span><span class="o">&amp;</span> <span class="n">src</span><span class="p">,</span>
           <span class="k">const</span> <span class="n">View</span><span class="o">::</span><span class="n">point_t</span><span class="o">&amp;</span> <span class="n">top_left</span><span class="p">,</span> <span class="k">const</span> <span class="n">View</span><span class="o">::</span><span class="n">point_t</span><span class="o">&amp;</span> <span class="n">dimensions</span><span class="p">);</span>

<span class="c1">// subsampled view (skipping pixels in X and Y)</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">View</span><span class="o">&gt;</span> <span class="k">typename</span> <span class="n">dynamic_xy_step_type</span><span class="o">&lt;</span><span class="n">View</span><span class="o">&gt;::</span><span class="n">type</span>            <span class="n">subsampled_view</span><span class="p">(</span><span class="k">const</span> <span class="n">View</span><span class="o">&amp;</span> <span class="n">src</span><span class="p">,</span>
           <span class="k">const</span> <span class="n">View</span><span class="o">::</span><span class="n">point_t</span><span class="o">&amp;</span> <span class="n">step</span><span class="p">);</span>

<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">View</span><span class="p">,</span> <span class="k">typename</span> <span class="n">P</span><span class="o">&gt;</span>
<span class="n">color_converted_view_type</span><span class="o">&lt;</span><span class="n">View</span><span class="p">,</span><span class="n">P</span><span class="o">&gt;::</span><span class="n">type</span>                                       <span class="n">color_converted_view</span><span class="p">(</span><span class="k">const</span> <span class="n">View</span><span class="o">&amp;</span> <span class="n">src</span><span class="p">);</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">View</span><span class="p">,</span> <span class="k">typename</span> <span class="n">P</span><span class="p">,</span> <span class="k">typename</span> <span class="n">CCV</span><span class="o">&gt;</span> <span class="c1">// with a custom color converter</span>
<span class="n">color_converted_view_type</span><span class="o">&lt;</span><span class="n">View</span><span class="p">,</span><span class="n">P</span><span class="p">,</span><span class="n">CCV</span><span class="o">&gt;::</span><span class="n">type</span>                                   <span class="n">color_converted_view</span><span class="p">(</span><span class="k">const</span> <span class="n">View</span><span class="o">&amp;</span> <span class="n">src</span><span class="p">);</span>

<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">View</span><span class="o">&gt;</span>
<span class="n">nth_channel_view_type</span><span class="o">&lt;</span><span class="n">View</span><span class="o">&gt;::</span><span class="n">view_t</span>                                           <span class="n">nth_channel_view</span><span class="p">(</span><span class="k">const</span> <span class="n">View</span><span class="o">&amp;</span> <span class="n">view</span><span class="p">,</span> <span class="kt">int</span> <span class="n">n</span><span class="p">);</span>
</pre></div>
</div>
<p>The implementations of most of these view factory methods are straightforward.
Here is, for example, how the flip views are implemented. The flip upside-down
view creates a view whose first pixel is the bottom left pixel of the original
view and whose y-step is the negated step of the source.</p>
<div class="highlight-cpp"><div class="highlight"><pre><span></span><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">View</span><span class="o">&gt;</span>
<span class="k">typename</span> <span class="n">dynamic_y_step_type</span><span class="o">&lt;</span><span class="n">View</span><span class="o">&gt;::</span><span class="n">type</span> <span class="n">flipped_up_down_view</span><span class="p">(</span><span class="k">const</span> <span class="n">View</span><span class="o">&amp;</span> <span class="n">src</span><span class="p">)</span>
<span class="p">{</span>
  <span class="n">gil_function_requires</span><span class="o">&lt;</span><span class="n">ImageViewConcept</span><span class="o">&lt;</span><span class="n">View</span><span class="o">&gt;</span> <span class="o">&gt;</span><span class="p">();</span>
  <span class="k">typedef</span> <span class="k">typename</span> <span class="n">dynamic_y_step_type</span><span class="o">&lt;</span><span class="n">View</span><span class="o">&gt;::</span><span class="n">type</span> <span class="n">RView</span><span class="p">;</span>
  <span class="k">return</span> <span class="nf">RView</span><span class="p">(</span><span class="n">src</span><span class="p">.</span><span class="n">dimensions</span><span class="p">(),</span><span class="k">typename</span> <span class="n">RView</span><span class="o">::</span><span class="n">xy_locator</span><span class="p">(</span><span class="n">src</span><span class="p">.</span><span class="n">xy_at</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="n">src</span><span class="p">.</span><span class="n">height</span><span class="p">()</span><span class="o">-</span><span class="mi">1</span><span class="p">),</span><span class="o">-</span><span class="mi">1</span><span class="p">));</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The call to <code class="docutils literal"><span class="pre">gil_function_requires</span></code> ensures (at compile time) that the
template parameter is a valid model of <code class="docutils literal"><span class="pre">ImageViewConcept</span></code>. Using it
generates easier to track compile errors, creates no extra code and has no
run-time performance impact. We are using the <code class="docutils literal"><span class="pre">boost::concept_check</span> <span class="pre">library</span></code>,
but wrapping it in <code class="docutils literal"><span class="pre">gil_function_requires</span></code>, which performs the check if the
<code class="docutils literal"><span class="pre">BOOST_GIL_USE_CONCEPT_CHECK</span></code> is set. It is unset by default, because there
is a significant increase in compile time when using concept checks. We will
skip <code class="docutils literal"><span class="pre">gil_function_requires</span></code> in the code examples in this guide for the sake
of succinctness.</p>
<p>Image views can be freely composed (see section <a class="reference internal" href="metafunctions.html"><span class="doc">Metafunctions</span></a> for
explanation of the typedefs <code class="docutils literal"><span class="pre">rgb16_image_t</span></code> and <code class="docutils literal"><span class="pre">gray16_step_view_t)</span></code>:</p>
<div class="highlight-cpp"><div class="highlight"><pre><span></span><span class="n">rgb16_image_t</span> <span class="nf">img</span><span class="p">(</span><span class="mi">100</span><span class="p">,</span><span class="mi">100</span><span class="p">);</span>    <span class="c1">// an RGB interleaved image</span>

<span class="c1">// grayscale view over the green (index 1) channel of img</span>
<span class="n">gray16_step_view_t</span> <span class="n">green</span><span class="o">=</span><span class="n">nth_channel_view</span><span class="p">(</span><span class="n">view</span><span class="p">(</span><span class="n">img</span><span class="p">),</span><span class="mi">1</span><span class="p">);</span>

<span class="c1">// 50x50 view of the green channel of img, upside down and taking every other pixel in X and in Y</span>
<span class="n">gray16_step_view_t</span> <span class="n">ud_fud</span><span class="o">=</span><span class="n">flipped_up_down_view</span><span class="p">(</span><span class="n">subsampled_view</span><span class="p">(</span><span class="n">green</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">2</span><span class="p">));</span>
</pre></div>
</div>
<p>As previously stated, image views are fast, constant-time, shallow views over
the pixel data. The above code does not copy any pixels; it operates on the
pixel data allocated when <code class="docutils literal"><span class="pre">img</span></code> was created.</p>
</div>
<div class="section" id="stl-style-algorithms-on-image-views">
<h3><a class="toc-backref" href="#id6">STL-Style Algorithms on Image Views</a></h3>
<p>Image views provide 1D iteration of their pixels via <code class="docutils literal"><span class="pre">begin()</span></code> and <code class="docutils literal"><span class="pre">end()</span></code>
methods, which makes it possible to use STL algorithms with them. However,
using nested loops over X and Y is in many cases more efficient.
The algorithms in this section resemble STL algorithms, but they abstract away
the nested loops and take views (as opposed to ranges) as input.</p>
<div class="highlight-cpp"><div class="highlight"><pre><span></span><span class="c1">// Equivalents of std::copy and std::uninitialized_copy</span>
<span class="c1">// where ImageViewConcept&lt;V1&gt;, MutableImageViewConcept&lt;V2&gt;, ViewsCompatibleConcept&lt;V1,V2&gt;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">V1</span><span class="p">,</span> <span class="k">typename</span> <span class="n">V2</span><span class="o">&gt;</span>
<span class="kt">void</span> <span class="n">copy_pixels</span><span class="p">(</span><span class="k">const</span> <span class="n">V1</span><span class="o">&amp;</span> <span class="n">src</span><span class="p">,</span> <span class="k">const</span> <span class="n">V2</span><span class="o">&amp;</span> <span class="n">dst</span><span class="p">);</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">V1</span><span class="p">,</span> <span class="k">typename</span> <span class="n">V2</span><span class="o">&gt;</span>
<span class="kt">void</span> <span class="n">uninitialized_copy_pixels</span><span class="p">(</span><span class="k">const</span> <span class="n">V1</span><span class="o">&amp;</span> <span class="n">src</span><span class="p">,</span> <span class="k">const</span> <span class="n">V2</span><span class="o">&amp;</span> <span class="n">dst</span><span class="p">);</span>

<span class="c1">// Equivalents of std::fill and std::uninitialized_fill</span>
<span class="c1">// where MutableImageViewConcept&lt;V&gt;, PixelConcept&lt;Value&gt;, PixelsCompatibleConcept&lt;Value,V::value_type&gt;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">V</span><span class="p">,</span> <span class="k">typename</span> <span class="n">Value</span><span class="o">&gt;</span>
<span class="kt">void</span> <span class="n">fill_pixels</span><span class="p">(</span><span class="k">const</span> <span class="n">V</span><span class="o">&amp;</span> <span class="n">dst</span><span class="p">,</span> <span class="k">const</span> <span class="n">Value</span><span class="o">&amp;</span> <span class="n">val</span><span class="p">);</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">V</span><span class="p">,</span> <span class="k">typename</span> <span class="n">Value</span><span class="o">&gt;</span>
<span class="kt">void</span> <span class="n">uninitialized_fill_pixels</span><span class="p">(</span><span class="k">const</span> <span class="n">V</span><span class="o">&amp;</span> <span class="n">dst</span><span class="p">,</span> <span class="k">const</span> <span class="n">Value</span><span class="o">&amp;</span> <span class="n">val</span><span class="p">);</span>

<span class="c1">// Equivalent of std::for_each</span>
<span class="c1">// where ImageViewConcept&lt;V&gt;, boost::UnaryFunctionConcept&lt;F&gt;</span>
<span class="c1">// where PixelsCompatibleConcept&lt;V::reference, F::argument_type&gt;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">V</span><span class="p">,</span> <span class="k">typename</span> <span class="n">F</span><span class="o">&gt;</span>
<span class="n">F</span> <span class="n">for_each_pixel</span><span class="p">(</span><span class="k">const</span> <span class="n">V</span><span class="o">&amp;</span> <span class="n">view</span><span class="p">,</span> <span class="n">F</span> <span class="n">fun</span><span class="p">);</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">V</span><span class="p">,</span> <span class="k">typename</span> <span class="n">F</span><span class="o">&gt;</span>
<span class="n">F</span> <span class="n">for_each_pixel_position</span><span class="p">(</span><span class="k">const</span> <span class="n">V</span><span class="o">&amp;</span> <span class="n">view</span><span class="p">,</span> <span class="n">F</span> <span class="n">fun</span><span class="p">);</span>

<span class="c1">// Equivalent of std::generate</span>
<span class="c1">// where MutableImageViewConcept&lt;V&gt;, boost::UnaryFunctionConcept&lt;F&gt;</span>
<span class="c1">// where PixelsCompatibleConcept&lt;V::reference, F::argument_type&gt;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">V</span><span class="p">,</span> <span class="k">typename</span> <span class="n">F</span><span class="o">&gt;</span>
<span class="kt">void</span> <span class="n">generate_pixels</span><span class="p">(</span><span class="k">const</span> <span class="n">V</span><span class="o">&amp;</span> <span class="n">dst</span><span class="p">,</span> <span class="n">F</span> <span class="n">fun</span><span class="p">);</span>

<span class="c1">// Equivalent of std::transform with one source</span>
<span class="c1">// where ImageViewConcept&lt;V1&gt;, MutableImageViewConcept&lt;V2&gt;</span>
<span class="c1">// where boost::UnaryFunctionConcept&lt;F&gt;</span>
<span class="c1">// where PixelsCompatibleConcept&lt;V1::const_reference, F::argument_type&gt;</span>
<span class="c1">// where PixelsCompatibleConcept&lt;F::result_type, V2::reference&gt;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">V1</span><span class="p">,</span> <span class="k">typename</span> <span class="n">V2</span><span class="p">,</span> <span class="k">typename</span> <span class="n">F</span><span class="o">&gt;</span>
<span class="n">F</span> <span class="n">transform_pixels</span><span class="p">(</span><span class="k">const</span> <span class="n">V1</span><span class="o">&amp;</span> <span class="n">src</span><span class="p">,</span> <span class="k">const</span> <span class="n">V2</span><span class="o">&amp;</span> <span class="n">dst</span><span class="p">,</span> <span class="n">F</span> <span class="n">fun</span><span class="p">);</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">V1</span><span class="p">,</span> <span class="k">typename</span> <span class="n">V2</span><span class="p">,</span> <span class="k">typename</span> <span class="n">F</span><span class="o">&gt;</span>
<span class="n">F</span> <span class="n">transform_pixel_positions</span><span class="p">(</span><span class="k">const</span> <span class="n">V1</span><span class="o">&amp;</span> <span class="n">src</span><span class="p">,</span> <span class="k">const</span> <span class="n">V2</span><span class="o">&amp;</span> <span class="n">dst</span><span class="p">,</span> <span class="n">F</span> <span class="n">fun</span><span class="p">);</span>

<span class="c1">// Equivalent of std::transform with two sources</span>
<span class="c1">// where ImageViewConcept&lt;V1&gt;, ImageViewConcept&lt;V2&gt;, MutableImageViewConcept&lt;V3&gt;</span>
<span class="c1">// where boost::BinaryFunctionConcept&lt;F&gt;</span>
<span class="c1">// where PixelsCompatibleConcept&lt;V1::const_reference, F::first_argument_type&gt;</span>
<span class="c1">// where PixelsCompatibleConcept&lt;V2::const_reference, F::second_argument_type&gt;</span>
<span class="c1">// where PixelsCompatibleConcept&lt;F::result_type, V3::reference&gt;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">V1</span><span class="p">,</span> <span class="k">typename</span> <span class="n">V2</span><span class="p">,</span> <span class="k">typename</span> <span class="n">V3</span><span class="p">,</span> <span class="k">typename</span> <span class="n">F</span><span class="o">&gt;</span>
<span class="n">F</span> <span class="n">transform_pixels</span><span class="p">(</span><span class="k">const</span> <span class="n">V1</span><span class="o">&amp;</span> <span class="n">src1</span><span class="p">,</span> <span class="k">const</span> <span class="n">V2</span><span class="o">&amp;</span> <span class="n">src2</span><span class="p">,</span> <span class="k">const</span> <span class="n">V3</span><span class="o">&amp;</span> <span class="n">dst</span><span class="p">,</span> <span class="n">F</span> <span class="n">fun</span><span class="p">);</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">V1</span><span class="p">,</span> <span class="k">typename</span> <span class="n">V2</span><span class="p">,</span> <span class="k">typename</span> <span class="n">V3</span><span class="p">,</span> <span class="k">typename</span> <span class="n">F</span><span class="o">&gt;</span>
<span class="n">F</span> <span class="n">transform_pixel_positions</span><span class="p">(</span><span class="k">const</span> <span class="n">V1</span><span class="o">&amp;</span> <span class="n">src1</span><span class="p">,</span> <span class="k">const</span> <span class="n">V2</span><span class="o">&amp;</span> <span class="n">src2</span><span class="p">,</span> <span class="k">const</span> <span class="n">V3</span><span class="o">&amp;</span> <span class="n">dst</span><span class="p">,</span> <span class="n">F</span> <span class="n">fun</span><span class="p">);</span>

<span class="c1">// Copies a view into another, color converting the pixels if needed, with the default or user-defined color converter</span>
<span class="c1">// where ImageViewConcept&lt;V1&gt;, MutableImageViewConcept&lt;V2&gt;</span>
<span class="c1">// V1::value_type must be convertible to V2::value_type.</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">V1</span><span class="p">,</span> <span class="k">typename</span> <span class="n">V2</span><span class="o">&gt;</span>
<span class="kt">void</span> <span class="n">copy_and_convert_pixels</span><span class="p">(</span><span class="k">const</span> <span class="n">V1</span><span class="o">&amp;</span> <span class="n">src</span><span class="p">,</span> <span class="k">const</span> <span class="n">V2</span><span class="o">&amp;</span> <span class="n">dst</span><span class="p">);</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">V1</span><span class="p">,</span> <span class="k">typename</span> <span class="n">V2</span><span class="p">,</span> <span class="k">typename</span> <span class="n">ColorConverter</span><span class="o">&gt;</span>
<span class="kt">void</span> <span class="n">copy_and_convert_pixels</span><span class="p">(</span><span class="k">const</span> <span class="n">V1</span><span class="o">&amp;</span> <span class="n">src</span><span class="p">,</span> <span class="k">const</span> <span class="n">V2</span><span class="o">&amp;</span> <span class="n">dst</span><span class="p">,</span> <span class="n">ColorConverter</span> <span class="n">ccv</span><span class="p">);</span>

<span class="c1">// Equivalent of std::equal</span>
<span class="c1">// where ImageViewConcept&lt;V1&gt;, ImageViewConcept&lt;V2&gt;, ViewsCompatibleConcept&lt;V1,V2&gt;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">V1</span><span class="p">,</span> <span class="k">typename</span> <span class="n">V2</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="n">equal_pixels</span><span class="p">(</span><span class="k">const</span> <span class="n">V1</span><span class="o">&amp;</span> <span class="n">view1</span><span class="p">,</span> <span class="k">const</span> <span class="n">V2</span><span class="o">&amp;</span> <span class="n">view2</span><span class="p">);</span>
</pre></div>
</div>
<p>Algorithms that take multiple views require that they have the same
dimensions. <code class="docutils literal"><span class="pre">for_each_pixel_position</span></code> and <code class="docutils literal"><span class="pre">transform_pixel_positions</span></code> pass
pixel locators, as opposed to pixel references, to their function objects.
This allows for writing algorithms that use pixel neighbours, as the tutorial
demonstrates.</p>
<p>Most of these algorithms check whether the image views are 1D-traversable.
A 1D-traversable image view has no gaps at the end of the rows.
In other words, if an x_iterator of that view is advanced past the last pixel
in a row it will move to the first pixel of the next row. When image views are
1D-traversable, the algorithms use a single loop and run more efficiently.
If one or more of the input views are not 1D-traversable, the algorithms
fall-back to an X-loop nested inside a Y-loop.</p>
<p>The algorithms typically delegate the work to their corresponding STL
algorithms. For example, <code class="docutils literal"><span class="pre">copy_pixels</span></code> calls <code class="docutils literal"><span class="pre">std::copy</span></code> either for each
row, or, when the images are 1D-traversable, once for all pixels.</p>
<p>In addition, overloads are sometimes provided for the STL algorithms.
For example, <code class="docutils literal"><span class="pre">std::copy</span></code> for planar iterators is overloaded to perform
<code class="docutils literal"><span class="pre">std::copy</span></code> for each of the planes. <code class="docutils literal"><span class="pre">std::copy</span></code> over bitwise-copyable
pixels results in <code class="docutils literal"><span class="pre">std::copy</span></code> over unsigned char, which STL
implements via <code class="docutils literal"><span class="pre">memmove</span></code>.</p>
<p>As a result <code class="docutils literal"><span class="pre">copy_pixels</span></code> may result in a single call to <code class="docutils literal"><span class="pre">memmove</span></code> for
interleaved 1D-traversable views, or one per each plane of planar
1D-traversable views, or one per each row of interleaved non-1D-traversable
images, etc.</p>
<p>GIL also provides some beta-versions of image processing algorithms, such as
resampling and convolution in a numerics extension available on
<a class="reference external" href="http://stlab.adobe.com/gil/download.html">http://stlab.adobe.com/gil/download.html</a>. This code is in early stage of
development and is not optimized for speed</p>
</div>
</div>
</div>


    <div class="navbar" style="text-align:right;">
      
      
      <a class="prev" title="Pixel Locator" href="pixel_locator.html"><img src="../_static/prev.png" alt="prev"/></a>
      <a class="up" title="Design Guide" href="index.html"><img src="../_static/up.png" alt="up"/></a>
      <a class="next" title="Image" href="image.html"><img src="../_static/next.png" alt="next"/></a>
      
    </div>
    </div>
    <div class="footer" role="contentinfo">
      Last updated on 2022-04-06 21:04:50.
      Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.5.6.
    </div>
  </body>
</html>